/* 
 * File:   vfd_graphics.h
 * Author: root
 *
 * Created on 23 февраля 2015 г., 3:47
 */

#ifndef VFD_GRAPHICS_H
#define	VFD_GRAPHICS_H

#include <stdint.h>
#include <string.h>

#define HEIGHT 64/8
#define WIDTH 128
#define SET_GRAY

#ifdef SET_GRAY
#define GRAY 2
#else
#define GRAY 1
#endif

typedef struct {
    uint8_t buffer[WIDTH*HEIGHT*GRAY];
} graphics_t;

static void set_pixel(graphics_t* graphics, int16_t x, int16_t y, uint8_t val) {
    if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT * 8) return;
    graphics->buffer[(16 * x)+(y / 4)] ^= (val << 6 - (y * 2) % 8);
}

static void h_line(graphics_t* graphics, int16_t x_from, int16_t x_to, int16_t y, uint8_t val) {
    if(x_from>=WIDTH) x_from=WIDTH;
    if(x_to>=WIDTH) x_to=WIDTH;
    if(x_from<0) x_from=-1;
    if(x_to<0) x_to=-1;
    int16_t x_n = x_to + 1;
    while (x_from != x_n) {
        x_n--;
        set_pixel(graphics, x_n, y, val);
    }
}

static void draw_h_line(graphics_t* graphics, int16_t x_from, int16_t x_to, int16_t y, uint8_t val) {
    if(x_from <= x_to) h_line(graphics,x_from,x_to,y,val);
    else h_line(graphics,x_to,x_from,y,val);
}

static void v_line(graphics_t* graphics, int16_t x, int16_t y_from, int16_t y_to, uint8_t val) {
    if(y_from>=HEIGHT*8) y_from=HEIGHT*8;
    if(y_to>=HEIGHT*8) y_to=HEIGHT*8;
    if(y_from<0) y_from=-1;
    if(y_to<0) y_to=-1;
    while (y_from != y_to) {
        y_to--;
        set_pixel(graphics, x, y_to, val);
    }
}

static void draw_v_line(graphics_t* graphics, int16_t x, int16_t y_from, int16_t y_to, uint8_t val) {
    if(y_from <= y_to) v_line(graphics,x,y_from,y_to,val);
    else v_line(graphics,x,y_to,y_from,val);
}

static void graphics_clear(graphics_t* graphics) {
    memset(graphics->buffer, 0x00, WIDTH*HEIGHT*GRAY);
}

#endif	/* VFD_GRAPHICS_H */

